﻿using IBatisNet.DataMapper;
using Janus.BaseEntitys;
using Janus.Cores.Repositories;
using Janus.Mes.ORM.iBatis;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Janus.Cores.Extension;
using System.Linq.Expressions;
using Janus.Cores.Linq;
using Janus.Cores.Tools;
using System.Reflection;
using System.Data;
using IBatisNet.DataMapper.MappedStatements;
using IBatisNet.DataMapper.Configuration.Statements;
using IBatisNet.DataMapper.Commands;
using IBatisNet.DataMapper.Scope;
using System.Data.SqlClient;

namespace Janus.Mes.Repositories.iBatis
{
    public abstract class iBatisRepository<T> : IRepository<ISqlMapper> where T : BaseEntitys.Entity, new()
    {
        protected static readonly string nameSpace = typeof(T).Name;
        #region 属性
        public virtual IRepositoryContext<ISqlMapper> CurrContext
        {
            get
            {
                var path = AppDomain.CurrentDomain.BaseDirectory + "\\sqlmap.config";//EBSHelper.GeBin()
                return new iBatisRepositoryContext(path);
            }
        }

        public virtual ISqlMapper Context
        {
            get
            {
                return this.CurrContext.Context;
            }
        }
        #endregion
        public iBatisRepository()
        { }


        #region 通用Statement
        /// <summary>  
        /// 新增  
        /// </summary>  
        protected virtual string InsertStatement { get { return nameSpace + ".Insert"; } }

        /// <summary>
        /// 新增多条
        /// </summary>
        protected virtual string InsertManyStatement { get { return nameSpace + ".InsertMany"; } }

        /// <summary>
        /// 根据主健保存记录，不存在则新增
        /// </summary>
        protected virtual string SaveStatement { get { return nameSpace + ".Save"; } }

        /// <summary>
        /// 根据主健保存多条记录，不存在则新增
        /// </summary>
        protected virtual string SaveManyStatement { get { return nameSpace + ".SaveMany"; } }

        /// <summary>  
        /// 编辑对象  
        /// </summary>  
        protected virtual string UpdateStatement { get { return nameSpace + ".Update"; } }

        /// <summary>
        /// 编辑部分
        /// </summary>
        protected virtual string UpdateSetionStatement { get { return nameSpace + ".UpdateSetion"; } }

        /// <summary>  
        /// 主健删除  
        /// </summary>  
        protected virtual string DeleteStatement { get { return nameSpace + ".Delete"; } }

        /// <summary>
        /// 自定义条件删除
        /// </summary>
        protected virtual string DeleteWhereStatement { get { return nameSpace + ".DeleteWhere"; } }

        /// <summary>  
        /// 单查  
        /// </summary>  
        protected virtual string FindOneStatement { get { return nameSpace + ".FindOne"; } }

        /// <summary>  
        /// Count  
        /// </summary>  
        protected virtual string FindAllCountStatement { get { return nameSpace + ".FindAllCount"; } }

        /// <summary>  
        /// 分页查询  
        /// </summary>  
        protected virtual string FindByPageStatement { get { return nameSpace + ".FindByPage"; } }

        /// <summary>  
        /// Full Query  
        /// </summary>  
        protected virtual string FindAllStatement { get { return nameSpace + ".FindAll"; } }

        /// <summary>
        /// 根据条件获取数据
        /// </summary>
        protected virtual string FindAllConditionStatement { get { return nameSpace + ".FindAllCondition"; } }

        /// <summary>
        /// 存储过程分页
        /// </summary>
        protected virtual string FindByPageProStatement { get { return "Public.ProcGetPageData"; } }

        /// <summary>
        /// 更新停用状态
        /// </summary>
        protected virtual string UpdateIsEnableStatement { get { return "Public.UpdateIsEnable"; } }

        /// <summary>
        /// 获取第一行第一列值
        /// </summary>
        protected virtual string FindScalarStatement { get { return nameSpace + ".FindScalar"; } }

        #endregion

        #region 是否存在
        /// <summary>
        /// 是否存在
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual bool IsExists<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : Entity
        {
            return this.Context.QueryForObject<TEntity>(this.FindAllConditionStatement, predicate.ToWhere()) != null;
        }
        public virtual bool IsExists(string predicate)
        {
            return this.Context.QueryForObject(this.FindAllConditionStatement, predicate) != null;
        }

        public virtual bool IsExists<TEntity>(Querier predicate) where TEntity : Entity
        {
            if (predicate == null) return false;
            string parameterObject = null;
            var e = predicate.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where;
            }
            return IsExists(parameterObject);
        }
        #endregion

        #region 新增
        /// <summary>
        /// 插入单条记录
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Add<T>(T entity) where T : Entity
        {
            bool result = false;
            try
            {
                entity.Id = entity.Id.IsGuid() ? entity.Id : entity.NewGuid2();
                var o = this.Context.Insert(this.InsertStatement, entity);
                result = true;
            }
            catch (Exception)
            {

                throw;
            }
            return result;
        }

        /// <summary>
        /// 插入多条记录
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public virtual bool Add<T>(List<T> entitys) where T : Entity
        {
            //Func<bool> fun = () =>
            //{
            //    return entitys.TrueForAll(c => this.Add(c));
            //};
            //return this.Transaction(fun);
            var result = this.BatchStart<T>(new iSqlBatcher(typeof(SqlDataAdapter)), entitys, 0);
            return result > 0;
        }

        #endregion

        #region 更新
        /// <summary>
        /// 根据主健保存记录，不存在则新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual int Save<T>(T entity) where T : Entity
        {
            entity.Id = entity.Id.IsGuid() ? entity.Id : entity.NewGuid2();
            return this.Context.Update(this.SaveStatement, entity);
        }

        /// <summary>
        /// 根据主健保存多条记录，不存在则新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Save<T>(List<T> entitys) where T : Entity
        {
            //Func<bool> fun = () =>
            //{
            //    return entitys.TrueForAll(c => this.Save(c) > 0);
            //};
            //return this.Transaction(fun);
            var currentBatcher = new iSqlBatcher(typeof(SqlDataAdapter));
            this.BatchStart<T>(currentBatcher, entitys, 1, false, this.SaveStatement);
            var result = currentBatcher.ExecuteBatch();
            currentBatcher.EndBatch();
            return result > 0;
        }

        /// <summary>
        /// 根据主健编辑对象
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual int Update<T>(T entity) where T : Entity
        {
            return this.Context.Update(this.UpdateStatement, entity);
        }

        /// <summary>
        /// 根据主健更新列表
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        public virtual bool Update<T>(List<T> entitys) where T : Entity
        {
            //Func<bool> fun = () =>
            //{
            //    return entitys.TrueForAll(c => this.Update(c) > 0);
            //};
            //return this.Transaction(fun);
            var result = this.BatchStart<T>(new iSqlBatcher(typeof(SqlDataAdapter)), entitys, 0);
            return result > 0;
        }

        /// <summary>
        /// 更新部分类
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public virtual int UpdateSetion(DynamicEntity entity, Conditioner conditions)
        {
            var hashtb = entity.ToHashtable();
            hashtb.Add("conditions", conditions.ToWhere);
            return this.Context.Update(this.UpdateSetionStatement, hashtb);
        }

        public virtual int UpdateSetion<TEntity>(DynamicEntity entity, Querier queriers) where TEntity : Entity
        {
            if (queriers == null) return 0;
            string parameterObject = null;
            var e = queriers.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where;
                return UpdateSetion(entity.ToHashtable(), parameterObject);
            }
            return 0;
        }
        /// <summary>
        /// 更新部分类
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public virtual int UpdateSetion<T>(T entity, Conditioner conditions) where T : Entity
        {
            entity.Id = entity.Id.IsGuid() ? entity.Id : entity.NewGuid2();
            var hashtb = entity.ToHashtable();
            hashtb.Add("conditions", conditions.ToWhere);
            return this.Context.Update(this.UpdateSetionStatement, hashtb);
        }

        public virtual int UpdateSetion<T>(T entity, Querier queriers) where T : Entity
        {
            entity.Id = entity.Id.IsGuid() ? entity.Id : entity.NewGuid2();
            var hashtb = entity.ToHashtable();
            if (queriers == null) return 0;
            string parameterObject = null;
            var e = queriers.ToExpression<T, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where;
                return UpdateSetion(hashtb, parameterObject);
            }
            return 0;
        }

        /// <summary>
        /// 更新部份类
        /// </summary>
        /// <param name="updater"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual int UpdateSetion<TEntity>(Expression<Func<TEntity, TEntity>> updater, Expression<Func<TEntity, bool>> predicate) where TEntity : Entity
        {
            var hashtb = updater.ToHashtable();
            hashtb.Add("conditions", predicate.ToWhere());
            return this.Context.Update(this.UpdateSetionStatement, hashtb);
        }

        public virtual int UpdateSetion(Hashtable updater, string predicate)// where TEntity : Entity
        {
            if (updater != null && updater.Count > 0)
            {
                updater.Add("conditions", predicate);
                return this.Context.Update(this.UpdateSetionStatement, updater);
            }
            else
                return 0;
        }

        public virtual int UpdateSetion<TEntity>(Hashtable updater, Querier queriers) where TEntity : Entity
        {
            if (queriers == null) return 0;
            string parameterObject = null;
            var e = queriers.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where;
                return UpdateSetion(updater, parameterObject);
            }
            return 0;
        }

        public virtual bool UpdateIsEnable<TEntity>(Querier queriers) where TEntity : Entity
        {
            bool result = false;
            if (queriers == null) return false;
            string parameterObject = null;
            var e = queriers.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = " AND " + reExpression.Where;
                var hashtb = new Hashtable();
                hashtb.Add("table", typeof(TEntity).Name);
                hashtb.Add("condition", parameterObject);
                result = this.Context.Update(UpdateIsEnableStatement, hashtb) > 0;
            }
            return result;
        }
        #endregion

        #region 删除
        /// <summary>
        /// 根据主键删除对象
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Delete(params object[] entity)
        {
            var hashtb = new Hashtable();
            if (entity.Length > 0)
            {
                int i = 0;
                entity.ToList().ForEach(c =>
                {
                    hashtb.Add("pk" + i, c);
                    i++;
                });
            }
            return this.Context.Delete(this.DeleteStatement, hashtb) > 0;
        }

        /// <summary>
        /// 根据复杂条件删除数据
        /// </summary>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public virtual bool Delete(Conditioner conditions)
        {
            return this.Context.Delete(this.DeleteWhereStatement, conditions.ToWhere) > 0;
        }

        /// <summary>
        /// 根据复杂条件删除数据
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual bool Delete<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : Entity
        {
            return this.Context.Delete(this.DeleteWhereStatement, predicate.ToWhere()) > 0;
        }

        public virtual bool Delete(string predicate) //where TEntity : Entity
        {
            return this.Context.Delete(this.DeleteWhereStatement, predicate) > 0;
        }
        public virtual bool Delete<TEntity>(Querier queriers) where TEntity : Entity
        {
            if (queriers == null) return false;
            string parameterObject = null;
            var e = queriers.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where;
                return Delete(parameterObject);
            }
            return false;
        }
        #endregion

        #region 查询
        /// <summary>
        /// 根据指定条件查询并返回指定字段
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="field">返回字段</param>
        /// <param name="predicate">指定条件</param>
        /// <returns></returns>
        public virtual object FindScalar<TEntity>(Expression<Func<TEntity, string>> field, Expression<Func<TEntity, bool>> predicate) where TEntity : Entity
        {
            var hashtb = new Hashtable();
            hashtb.Add("conditions", predicate.ToWhere());
            var result = this.Context.QueryForObject<TEntity>(this.FindScalarStatement, hashtb);
            return RelfHelper.GetValue(result, field.GetName());
        }

        public virtual object FindScalar<TEntity>(string field, string predicate) where TEntity : Entity
        {
            var hashtb = new Hashtable();
            hashtb.Add("conditions", predicate);
            var result = this.Context.QueryForObject<TEntity>(this.FindScalarStatement, hashtb);
            return RelfHelper.GetValue(result, field);
        }

        public virtual object FindScalar<TEntity>(string field, Querier queriers) where TEntity : Entity
        {
            if (queriers == null) return null;
            string parameterObject = null;
            var e = queriers.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where + " " + queriers.Orders;
                return FindScalar<TEntity>(field, parameterObject);
            }
            return null;
        }
        /// <summary>
        /// 根据主键获取单个对象
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual T FindOne<T>(params object[] entity)
        {
            var hashtb = new Hashtable();
            if (entity.Length > 0)
            {
                int i = 0;
                entity.ToList().ForEach(c =>
                {
                    hashtb.Add("pk" + i, c);
                    i++;
                });
            }
            return this.Context.QueryForObject<T>(this.FindOneStatement, hashtb);
        }

        /// <summary>
        /// 根据条件获取一个对象
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual TEntity FindOne<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : Entity
        {
            return this.Context.QueryForObject<TEntity>(this.FindAllConditionStatement, predicate.ToWhere());
        }

        public virtual TEntity FindOne<TEntity>(string predicate) where TEntity : Entity
        {
            return this.Context.QueryForObject<TEntity>(this.FindAllConditionStatement, predicate);
        }

        public virtual TEntity FindOne<TEntity>(Querier queriers) where TEntity : Entity
        {
            if (queriers == null) return null;
            string parameterObject = null;
            var e = queriers.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where + " " + queriers.Orders;
                return FindOne<TEntity>(parameterObject);
            }
            return null;
        }

        /// <summary>
        /// 根据条件获取列表数据
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual IList<TEntity> FindAll<TEntity>(Expression<Func<TEntity, bool>> predicate, string orderBy = null) where TEntity : Entity
        {
            orderBy = !string.IsNullOrEmpty(orderBy) ? " ORDER BY " : string.Empty;
            return this.Context.QueryForList<TEntity>(this.FindAllConditionStatement, predicate == null ? " 1=1 " : predicate.ToWhere() + " " + orderBy);
        }

        public virtual IList<TEntity> FindAll<TEntity>(Querier queriers) where TEntity : Entity
        {
            if (queriers == null) return null;
            string parameterObject = null;
            var e = queriers.ToExpression<TEntity, bool>();
            if (e != null)
            {
                ResolveExpression reExpression = new ResolveExpression();
                reExpression.ResolveToSql(e);
                parameterObject = reExpression.Where + " " + queriers.Orders;
            }
            return this.Context.QueryForList<TEntity>(this.FindAllConditionStatement, parameterObject ?? " 1=1 ");
        }

        public virtual IList<TEntity> FindAll<TEntity>(string predicate, string orderBy = null) where TEntity : Entity
        {
            return this.Context.QueryForList<TEntity>(this.FindAllConditionStatement, predicate ?? " 1=1 " + " " + orderBy);
        }

        /// <summary>
        /// 返回数据列表
        /// </summary>
        /// <param name="searchEntity"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public virtual ResponseResult<IList<TEntity>> FindAll<TEntity>(SearchEntity<TEntity> searchEntity) where TEntity : Entity, new()
        {
            return this.FindAll(searchEntity, this.FindAllCountStatement, this.FindByPageStatement,
                this.FindAllStatement);
        }

        /// <summary>
        /// 使用存储过程分页
        /// </summary>
        /// <param name="searchEntity"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public virtual ResponseResult<IList<TEntity>> FindAllByPro<TEntity>(PageCriteria pageCriteria) where TEntity : Entity, new()
        {
            var totalCount = 0;
            ResponseResult<IList<TEntity>> result = new ResponseResult<IList<TEntity>>();
            if (pageCriteria != null)
            {
                result.Pagination = new PaginationDTO();
                result.Pagination.CurrentIndex = pageCriteria.CurrentPage;
                result.Pagination.PageSize = pageCriteria.PageSize;

                PageCriteria criteria = pageCriteria ?? new PageCriteria();
                criteria.TableName = typeof(T).Name;
                criteria.PrimaryKey = "Id";
                criteria.Fields = @"*";
                var dataHash = this.Context.QueryForList<Hashtable>(this.FindByPageProStatement, pageCriteria);
                if (dataHash != null && dataHash.Count > 1)
                {
                    result.Result = dataHash.ToEntity<TEntity>();
                    result.Pagination.RowCount = pageCriteria.RecordCount;
                }
                return result;
            }
            return result;
        }

        /// <summary>  
        /// 分页查询（如果searchEntity没有指定或者指定Size,Index不正确，则查询所有数据）  
        /// </summary>  
        /// <param name="searchEntity"></param>  
        /// <param name="queryCountStatement"></param>  
        /// <param name="queryPagedListStatement"></param>  
        /// <param name="queryAllStatement"></param>  
        /// <param name="totalCount"></param>  
        /// <returns></returns>  
        public virtual ResponseResult<IList<TEntity>> FindAll<TEntity>(SearchEntity<TEntity> searchEntity,
            string queryCountStatement, string queryPagedListStatement, string queryAllStatement)
            where TEntity : Entity, new()
        {
            var totalCount = 0;
            ResponseResult<IList<TEntity>> result = new ResponseResult<IList<TEntity>>();
            object parameterObject = "1=1";
            object parameterObjectOrder = "1=1";
            if (searchEntity != null && searchEntity.Queriers != null)
            {
                var e = searchEntity.Queriers.ToExpression<TEntity, bool>();
                if (e != null)
                {
                    ResolveExpression reExpression = new ResolveExpression();
                    reExpression.ResolveToSql(e);
                    parameterObject = reExpression.Where;
                    parameterObjectOrder = parameterObject + " " + searchEntity.Queriers.Orders;
                }
            }
            if (searchEntity != null && searchEntity.Pagination != null && searchEntity.Pagination.IsPaging)
            {
                result.Pagination = searchEntity.Pagination;
                if (searchEntity.Pagination.ReCount)
                {
                    //分页  
                    totalCount = this.Context.QueryForObject<int>(queryCountStatement, parameterObject);
                }
                else
                {
                    totalCount = searchEntity.Pagination.RowCount.Value;
                }

                if (totalCount > 0)
                {
                    int skipResults = (searchEntity.Pagination.CurrentIndex - 1) * searchEntity.Pagination.PageSize;
                    int maxResults = searchEntity.Pagination.PageSize;
                    result.Result = this.Context.QueryForList<TEntity>(queryPagedListStatement, parameterObjectOrder, skipResults, maxResults);
                    result.Pagination.RowCount = totalCount;
                }
            }
            else
            {
                //获取所有数据  
                result.Result = this.Context.QueryForList<TEntity>(queryAllStatement, parameterObjectOrder);
                result.Pagination.RowCount = totalCount;
            }
            return result;
        }


        #endregion

        #region 事务
        /// <summary>  
        /// 单数据库事务  
        /// </summary>  
        /// <param name="fun"></param>  
        /// <returns></returns>  
        protected bool Transaction(Func<bool> fun)
        {
            using (var session = this.Context.BeginTransaction())
            {
                try
                {
                    bool result = fun();
                    session.Complete();
                    return result;
                }
                catch (Exception ex)
                {
                    session.RollBackTransaction();
                    //TODO:log  
                    throw;
                }
            }
        }
        #endregion

        #region 扩展
        public string GetSql(string tag, object paramObject)
        {
            var mappstatment = this.Context.GetMappedStatement(tag);
            var statement = mappstatment.Statement;
            var request = statement.Sql.GetRequestScope(mappstatment, paramObject, new SqlMapSession(this.Context));
            return request.PreparedStatement.PreparedSql;
        }
        #endregion

        #region 批量操作
        /// <summary>
        /// 批量插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public bool BatchInset<T>(List<T> models) where T : Entity
        {
            AdoBatcher batcher = new AdoBatcher(this.Context);
            return batcher.BatchInsert<T>(models);
        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public bool BatchUpdate<T>(List<T> models) where T : Entity
        {
            AdoBatcher batcher = new AdoBatcher(this.Context);
            return batcher.BatchUpdate<T>(models);
        }

        /// <summary>
        /// 批量更新或插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public bool BatchSave<T>(List<T> models) where T : Entity
        {
            AdoBatcher batcher = new AdoBatcher(this.Context);
            return batcher.BatchSave<T>(models);
        }

        /// <summary>
        /// 批量保存 -1 根据RowState生成 0 新增 1 修改 2 删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="recordArray">数据集</param>
        /// <param name="opType">-1 根据RowState生成 0 新增 1 修改 2 删除</param>
        /// <returns></returns>
        public int BatchStart<T>(iSqlBatcher m_Batcher, List<T> recordArray, int opType = -1, bool isComite = true, string statementId = null) where T : Entity
        {
            if (recordArray == null)
                throw new ArgumentNullException("recordArray");
            if (recordArray.Count < 1)
                throw new ArgumentException("recordArray");
            ISqlMapper mapper = Context;
            if (mapper.LocalSession == null)
                mapper.OpenConnection();
            ISqlMapSession session = mapper.LocalSession;
            IMappedStatement mappedStatment = null;
            IStatement st = null;
            IPreparedCommand pc = null;
            RequestScope request = null;

            if (opType != -1)
            {
                if (statementId.IsNotEmpty())
                {
                    mappedStatment = mapper.GetMappedStatement(statementId);
                }
                else
                {
                    switch (opType)
                    {
                        case 0:
                            mappedStatment = mapper.GetMappedStatement(this.InsertStatement);
                            break;
                        case 1:
                            mappedStatment = mapper.GetMappedStatement(this.UpdateStatement);
                            break;
                        case 2:
                            mappedStatment = mapper.GetMappedStatement(this.DeleteStatement);
                            break;
                    }
                }
                st = mappedStatment.Statement;
                pc = mappedStatment.PreparedCommand;
                request = st.Sql.GetRequestScope(mappedStatment, recordArray[0], session);
            }

            m_Batcher = m_Batcher ?? new iSqlBatcher(typeof(SqlDataAdapter));
            // 执行批处理命令
            m_Batcher.StartBatch(session.Connection);
#if DEBUG
            var m_Watch = new System.Diagnostics.Stopwatch();
            m_Watch.Start();
#endif
            foreach (T record in recordArray)
            {
                if (opType == -1 && mappedStatment == null)
                {
                    switch (record.RowState)
                    {
                        case DataRowState.Added:
                            mappedStatment = mapper.GetMappedStatement(this.InsertStatement);
                            break;
                        case DataRowState.Modified:
                            mappedStatment = mapper.GetMappedStatement(this.UpdateStatement);
                            break;
                        case DataRowState.Deleted:
                            mappedStatment = mapper.GetMappedStatement(this.DeleteStatement);
                            break;
                    }
                    st = mappedStatment.Statement;
                    pc = mappedStatment.PreparedCommand;
                    request = st.Sql.GetRequestScope(mappedStatment, recordArray[0], session);
                }
                pc.Create(request, session, st, record);
                m_Batcher.AddToBatch(GetCommand(request.IDbCommand));
            }
#if DEBUG
            m_Watch.Stop();
            System.Diagnostics.Trace.WriteLine(string.Format("准备数据用了 {0} 毫秒。", m_Watch.ElapsedMilliseconds));
            m_Watch.Reset();
#endif
            session.OpenConnection();
#if DEBUG
            m_Watch.Start();
#endif
            int ret = 0;
            if (isComite)
            {
                ret = m_Batcher.ExecuteBatch();
                m_Batcher.EndBatch();
            }
#if DEBUG
            m_Watch.Stop();
            System.Diagnostics.Trace.WriteLine(string.Format("批量插入数据用了 {0} 毫秒。", m_Watch.ElapsedMilliseconds));
#endif
            return ret;

        }

        //由于IBatisNet 用 DbCommandDecorator 包装了 DbCommand，因此必须使用反射取得该字段
        private static readonly FieldInfo m_InnerCommandField = typeof(IBatisNet.DataMapper.Commands.DbCommandDecorator).GetField("_innerDbCommand", BindingFlags.Instance | BindingFlags.NonPublic);

        // 转化 IBatis 包装后的 DbCommand 为 原始的 DbCommand
        private static IDbCommand GetCommand(IDbCommand ibatCommand)
        {
            return (IDbCommand)m_InnerCommandField.GetValue(ibatCommand);
        }
        #endregion
    }
}
